| Author | Manuela Ruiz (mruiz@lcc.uma.es) |
This class represents a LabelledShape, that is, a shape with any number of labels
| edges | list of edges |
| points_and_materials | list of pairs (point, material) |
Initializes the hashes of maximal lines and labelled points, associated with layer 0
# File lib/geometry.rb, line 611
611: def initialize(edges, points_and_materials)
612: if !@s
613: @s = Hash.new(nil)
614: if Shade.using_sketchup
615: Sketchup.active_model.layers.each { |layer|
616: @s[layer.name] = LinearLinkedList.new
617: }
618: else
619: @s["Layer0"] = LinearLinkedList.new
620: end
621: end
622: if !@p
623: @p = Hash.new(nil)
624: if Shade.using_sketchup
625: Sketchup.active_model.layers.each { |layer|
626: @p[layer.name] = LinearLinkedList.new
627: }
628: else
629: @p["Layer0"] = LinearLinkedList.new
630: end
631: end
632: edges.each { |e|
633: segment = Segment.new(OrderedPoint.new(e.start.position), OrderedPoint.new(e.end.position))
634: segment_list = LinearLinkedList.new
635:
636: if @s["Layer0"].kind_of? LinearLinkedList
637: node = LinearLinkedListNode.new(segment.line_descriptor, segment_list, nil)
638: else
639: node = BalancedBinaryTreeNode.new(Constants::BALANCED, nil, nil, segment.line_descriptor, segment_list)
640: end
641:
642: inserted_node = @s["Layer0"].insert_node(node) #Insert the node corresponding to the line descriptor of the segment
643:
644: #We create an auxiliar list filled with the new segment to add, in order to make the union and obtain the maximal lines
645: new_segment_list = LinearLinkedList.new
646: segment_node = LinearLinkedListNode.new(segment.clone, nil, nil)
647: new_segment_list.insert_node(segment_node)
648:
649: op_rel(inserted_node.list, new_segment_list, Constants::UNION, Constants::SEGMENTS)
650: }
651:
652: #Compound the label lists
653: points_and_materials.each { |pair|
654: point = OrderedPoint.new(pair[0])
655: label = Label.new(pair[1])
656: point_list = LinearLinkedList.new
657:
658: if @p["Layer0"].kind_of? LinearLinkedList
659: node = LinearLinkedListNode.new(label, point_list, nil)
660: else
661: node = BalancedBinaryTreeNode.new(Constants::BALANCED, nil, nil, label, point_list)
662: end
663:
664: inserted_node = @p["Layer0"].insert_node(node) #Insert the node corresponding to the label of the point
665:
666: point_node = LinearLinkedListNode.new(point, nil, nil)
667: inserted_node.list.insert_node(point_node) #Insert the point node
668: }
669: recompute_intersection_points
670: end
| point | a Point object |
| value | the name of the label value |
| layer_name | the name of the layer on which the label is going to be added |
Adds a label to the shape in the position determined by point, with the specified value and in the specified layer
# File lib/geometry.rb, line 731
731: def add_label(point, value, layer_name)
732: if @p[layer_name]
733: label = Label.new(value)
734: point_list = LinearLinkedList.new
735:
736: node = LinearLinkedListNode.new(label, point_list, nil)
737:
738: inserted_node = @p[layer_name].insert_node(node) #Insert the node corresponding to the label of the point
739:
740: point_node = LinearLinkedListNode.new(OrderedPoint.new(point), nil, nil)
741: inserted_node.list.insert_node(point_node) #Insert the point node
742: end
743: end
| returns | the hash code for this labelled shape |
# File lib/geometry.rb, line 1581
1581: def hash
1582: return [@s["Layer0"].hash, @p["Layer0"].hash].hash
1583: end
| path | path to load the shape from |
Loads the shape in the specified path
# File lib/geometry.rb, line 1326
1326: def load(path)
1327:
1328: if Shade.using_sketchup
1329: extension = ShadeUtils.get_extension(path)
1330:
1331: if extension == "skp"
1332:
1333: #We remove everything
1334: rules = Shade.project.execution.grammar.rules
1335: rules.each {|rule|
1336: rule.erase
1337: }
1338: Shade.project.execution.current_shape.erase
1339: Sketchup.active_model.active_entities.erase_entities(Sketchup.active_model.active_entities.to_a)
1340:
1341: path = path.tr("\\","/")
1342: Sketchup.active_model.save("trash.skp")
1343: Sketchup.open_file(path) #A group is loaded
1344: File.delete("trash.skp")
1345: entities = Sketchup.active_model.entities[0].entities
1346:
1347: edges = Array.new
1348: points_and_materials = Array.new
1349:
1350: entities.each { |e|
1351: if e.kind_of? Sketchup::Edge
1352: edges.push e
1353: elsif e.kind_of? Sketchup::Group
1354: e.entities.each { |ge|
1355: if ge.kind_of? Sketchup::ConstructionPoint
1356: points_and_materials.push [ge.position, e.material]
1357: end
1358: }
1359:
1360: end
1361: }
1362:
1363: self.refresh_from_info(edges, points_and_materials)
1364:
1365: Sketchup.active_model.active_entities.erase_entities(Sketchup.active_model.active_entities.to_a)
1366:
1367: #We repaint everything
1368: ShadeUtils.prepare_canvas(false)
1369: rules.each {|rule|
1370: rule.repaint
1371: }
1372: Shade.project.execution.current_shape.paint
1373: elsif extension == "txt"
1374: File.open(path, 'r') do |f|
1375: layer_found = false
1376: while line = f.gets
1377: line_a1 = line.split(":")
1378: if line_a1[0].strip == "S" #Segment
1379: if !layer_found
1380: if self.kind_of? CurrentLabelledShape
1381: @s["Layer0"] = BalancedBinaryTree.new
1382: else
1383: @s["Layer0"] = LinearLinkedList.new
1384: end
1385: @p["Layer0"] = LinearLinkedList.new
1386: layer_name = "Layer0"
1387: layer_found = true
1388: end
1389: line_a = line_a1[1].split
1390: segment = Segment.new(OrderedPoint.new(Geom::Point3d.new(line_a[0].to_f.m, line_a[1].to_f.m, 0)), OrderedPoint.new(Geom::Point3d.new(line_a[2].to_f.m, line_a[3].to_f.m, 0)))
1391: segment_list = LinearLinkedList.new
1392:
1393: if @s[layer_name].kind_of? LinearLinkedList
1394: node = LinearLinkedListNode.new(segment.line_descriptor, segment_list, nil)
1395: else
1396: node = BalancedBinaryTreeNode.new(Constants::BALANCED, nil, nil, segment.line_descriptor, segment_list)
1397: end
1398:
1399: inserted_node = @s[layer_name].insert_node(node) #Insert the node corresponding to the line descriptor of the segment
1400:
1401: #We create an auxiliar list filled with the new segment to add, in order to make the union and obtain the maximal lines
1402: new_segment_list = LinearLinkedList.new
1403: segment_node = LinearLinkedListNode.new(segment.clone, nil, nil)
1404: new_segment_list.insert_node(segment_node)
1405:
1406: op_rel(inserted_node.list, new_segment_list, Constants::UNION, Constants::SEGMENTS)
1407:
1408: elsif line_a1[0].strip == "L" #Label
1409: if !layer_found
1410: if self.kind_of? CurrentLabelledShape
1411: @s["Layer0"] = BalancedBinaryTree.new
1412: else
1413: @s["Layer0"] = LinearLinkedList.new
1414: end
1415: @p["Layer0"] = LinearLinkedList.new
1416: layer_name = "Layer0"
1417: layer_found = true
1418: end
1419: line_a = line_a1[1].split
1420: color = line_a[2]
1421: raise LoadError, "The color name: #{color} of shape in file #{path} is not recognized" unless Constants::RECOGNIZED_COLORS.include? color
1422:
1423: label = Label.new(line_a[2])
1424: point = OrderedPoint.new(Geom::Point3d.new(line_a[0].to_f.m, line_a[1].to_f.m, 0))
1425: point_list = LinearLinkedList.new
1426:
1427: if @p[layer_name].kind_of? LinearLinkedList
1428: node = LinearLinkedListNode.new(label, point_list, nil)
1429: else
1430: node = BalancedBinaryTreeNode.new(Constants::BALANCED, nil, nil, label, point_list)
1431: end
1432:
1433: inserted_node = @p[layer_name].insert_node(node) #Insert the node corresponding to the label of the point
1434:
1435: point_node = LinearLinkedListNode.new(point, nil, nil)
1436: inserted_node.list.insert_node(point_node) #Insert the point node
1437: elsif line_a1[0].strip == "LAYER" #Layer
1438: layer_name = line_a1[1].strip
1439: if self.kind_of? CurrentLabelledShape
1440: @s[layer_name] = BalancedBinaryTree.new
1441: else
1442: @s[layer_name] = LinearLinkedList.new
1443: end
1444: @p[layer_name] = LinearLinkedList.new
1445: layer_found = true
1446: end
1447: end
1448: end
1449: recompute_intersection_points
1450: #paint
1451: end
1452: else
1453: extension = ShadeUtils.get_extension(path)
1454:
1455: if extension == "txt"
1456: layer_name = "Layer0"
1457: File.open(path, 'r') do |f|
1458: layer_found = false
1459: while line = f.gets
1460: line_a1 = line.split(":")
1461: if line_a1[0].strip == "S" #Segment
1462: if !layer_found
1463: if self.kind_of? CurrentLabelledShape
1464: @s["Layer0"] = BalancedBinaryTree.new
1465: else
1466: @s["Layer0"] = LinearLinkedList.new
1467: end
1468: @p["Layer0"] = LinearLinkedList.new
1469: layer_name = "Layer0"
1470: layer_found = true
1471: end
1472: line_a = line_a1[1].split
1473: segment = Segment.new(OrderedPoint.new(Point.new(line_a[0].to_f, line_a[1].to_f, 0)), OrderedPoint.new(Point.new(line_a[2].to_f, line_a[3].to_f, 0)))
1474: segment_list = LinearLinkedList.new
1475:
1476: if @s[layer_name].kind_of? LinearLinkedList
1477: node = LinearLinkedListNode.new(segment.line_descriptor, segment_list, nil)
1478: else
1479: node = BalancedBinaryTreeNode.new(Constants::BALANCED, nil, nil, segment.line_descriptor, segment_list)
1480: end
1481:
1482: inserted_node = @s[layer_name].insert_node(node) #Insert the node corresponding to the line descriptor of the segment
1483:
1484: #We create an auxiliar list filled with the new segment to add, in order to make the union and obtain the maximal lines
1485: new_segment_list = LinearLinkedList.new
1486: segment_node = LinearLinkedListNode.new(segment.clone, nil, nil)
1487: new_segment_list.insert_node(segment_node)
1488:
1489: op_rel(inserted_node.list, new_segment_list, Constants::UNION, Constants::SEGMENTS)
1490:
1491: elsif line_a1[0].strip == "L" #Label
1492: if !layer_found
1493: if self.kind_of? CurrentLabelledShape
1494: @s["Layer0"] = BalancedBinaryTree.new
1495: else
1496: @s["Layer0"] = LinearLinkedList.new
1497: end
1498: @p["Layer0"] = LinearLinkedList.new
1499: layer_name = "Layer0"
1500: layer_found = true
1501: end
1502: line_a = line_a1[1].split
1503: color = line_a[2]
1504: raise LoadError, "The color name: #{color} of shape in file #{path} is not recognized" unless Constants::RECOGNIZED_COLORS.include? color
1505: label = Label.new(line_a[2])
1506: point = OrderedPoint.new(Point.new(line_a[0].to_f, line_a[1].to_f, 0))
1507: point_list = LinearLinkedList.new
1508:
1509: if @p[layer_name].kind_of? LinearLinkedList
1510: node = LinearLinkedListNode.new(label, point_list, nil)
1511: else
1512: node = BalancedBinaryTreeNode.new(Constants::BALANCED, nil, nil, label, point_list)
1513: end
1514:
1515: inserted_node = @p[layer_name].insert_node(node) #Insert the node corresponding to the label of the point
1516:
1517: point_node = LinearLinkedListNode.new(point, nil, nil)
1518: inserted_node.list.insert_node(point_node) #Insert the point node
1519: elsif line_a1[0].strip == "LAYER" #Layer
1520: layer_name = line_a1[1].strip
1521: if self.kind_of? CurrentLabelledShape
1522: @s[layer_name] = BalancedBinaryTree.new
1523: else
1524: @s[layer_name] = LinearLinkedList.new
1525: end
1526: @p[layer_name] = LinearLinkedList.new
1527: layer_found = true
1528: end
1529: end
1530: end
1531: recompute_intersection_points
1532: #paint
1533: end
1534: end
1535:
1536: end
list1: a LinearLinkedList of Segments or Points list2: a LinearLinkedList of Segments or Points
| op_rel_type | the operation or relation to perform. One of the following: Constants::UNION, Constants::INTERSECTION, Constants::DIFFERENCE, |
Constants::SUBSHAPE, Constants::EQUAL
| c | Constants::SEGMENT if segments are affected, Constants::POINTS if points are affected. |
returns::true iff the specified relation (subshape or equal) holds (or false if it does not hold). In case it is an union or difference operation, it just overwrites list1 with the resulting list of the operation. In case it is an intersection, it returns a new segment list.
# File lib/geometry.rb, line 952
952: def op_rel(list1, list2, op_rel_type, c)
953: if (c == Constants::SEGMENTS)
954: if (op_rel_type == Constants::UNION)
955: #Step 0
956: working_line_node = list2.first
957: linej_node = list1.first
958: if !list1.empty?
959: #Step 1
960: step1_union(list1, list2, working_line_node, linej_node)
961: else
962: #Step 8
963: #There may still be some unexamined lines in line2. Copy all the unexamined lines in line2 in their order, and attach them
964: #to the end of list list1
965: step8_union(list1, list2, working_line_node, linej_node)
966: end
967: elsif (op_rel_type == Constants::DIFFERENCE)
968: #Step 0
969: if !list1.empty?
970: #step 1
971: working_line_node = list2.first
972: linej_node = list1.first
973: step1_difference(list1, list2, working_line_node, linej_node)
974: end
975: elsif (op_rel_type == Constants::INTERSECTION)
976: if !list1.empty?
977: #Step 0
978: working_line_node = list2.first
979: linej_node = list1.first
980: list3 = LinearLinkedList.new
981: #step 1
982: step1_intersection(list1, list2, list3, working_line, linej)
983: end
984: elsif (op_rel_type == Constants::SUBSHAPE)
985: #step 0
986: flag = true
987: if !list1.empty?
988: #step 1
989: working_line_node = list2.first
990: linej_node = list1.first
991: flag = step1_subshape(flag, list1, list2, working_line_node, linej_node)
992: else
993: flag = (list2.empty?)
994: end
995: elsif (op_rel_type == Constants::EQUAL)
996: flag = (list1 == list2)
997: end
998: elsif (c == Constants::POINTS)
999: if (op_rel_type == Constants::UNION)
1000: list2.reset_iterator
1001: while n = list2.get_next
1002: point = n.key
1003: list1.insert_node(LinearLinkedListNode.new(point.clone, nil, nil))
1004: end
1005: elsif (op_rel_type == Constants::DIFFERENCE)
1006: list2.reset_iterator
1007: while n = list2.get_next
1008: point = n.key
1009: list1.delete_node(point)
1010: end
1011: elsif (op_rel_type == Constants::INTERSECTION)
1012: list3 = LinearLinkedList.new
1013: list2.reset_iterator
1014: while n = list2.get_next
1015: point = n.key
1016: if list1.get_node(point)
1017: list3.insert_node(LinearLinkedListNode.new(point.clone, nil, nil))
1018: end
1019: end
1020: elsif (op_rel_type == Constants::SUBSHAPE)
1021: flag = true
1022: list2.reset_iterator
1023: while (flag && n = list2.get_next)
1024: point = n.key
1025: flag = list1.get_node(point)
1026: if !flag
1027: flag = false
1028: else
1029: flag = true
1030: end
1031: end
1032: elsif (op_rel_type == Constants::EQUAL)
1033: flag = (list1 == list2)
1034: end
1035: end
1036:
1037: if (op_rel_type == Constants::INTERSECTION)
1038: return list3
1039: elsif (op_rel_type == Constants::SUBSHAPE) || (op_rel_type == Constants::EQUAL)
1040: return flag
1041: end
1042: end
Paints the view of the shape
# File lib/geometry.rb, line 1539
1539: def paint()
1540: if Shade.using_sketchup
1541: entities = Sketchup.active_model.entities
1542:
1543: layers = Sketchup.active_model.layers
1544:
1545: @s.each_key { |layer_name|
1546: @s[layer.name].reset_iterator
1547: while (node = @s[layer.name].get_next)
1548: node.list.reset_iterator
1549: while (segment_node = node.list.get_next)
1550: entities.add_edges segment_node.key.tail.point, segment_node.key.head.point
1551: end
1552: end
1553: }
1554:
1555: @p.each_key { |layer_name|
1556: @p[layer.name].reset_iterator
1557: while (node = @p[layer.name].get_next)
1558: label = node.key
1559: node.list.reset_iterator
1560: while (labelled_point_node = node.list.get_next)
1561: if !(label.value==Constants::INTERSECTION_LABEL) #The label is a coloured circle
1562: label_group = entities.add_group
1563:
1564: # Add circle
1565: edges = label_group.entities.add_circle labelled_point_node.key.point, Constants::LABEL_VECTOR, Shade.label_radius
1566: #Add construction point in order to locate the center later
1567: label_group.entities.add_cpoint labelled_point_node.key.point
1568: #Add face
1569: face = label_group.entities.add_face edges
1570: #Give color to the face
1571: label_group.material = label.value
1572: end
1573: end
1574: end
1575:
1576: }
1577: end
1578: end
Recompute the intersection points of the shape
# File lib/geometry.rb, line 862
862: def recompute_intersection_points(testing = false)
863:
864: @s.each_key { |layer_name|
865: #First, we remove the old intersection points, if any
866: @p[layer_name].delete_node(Label.new(Constants::INTERSECTION_LABEL))
867:
868: s_array = @s[layer_name].to_array
869:
870: #Second, we obtain the nodes of the maximal lines in order
871: @s[layer_name].reset_iterator
872: i = 0
873: while (node = @s[layer_name].get_next)
874: j = i
875: #Obtain next_node without breaking the iterator
876: while (j < s_array.size)
877: #puts "Comparing #{i} line with #{j} line"
878: next_node = s_array[j]
879: if !(next_node.key.sine == node.key.sine) #If line descriptors are not parallel...
880: current_segment_node = node.list.first
881: found1 = false
882: #While there are segments in node and the intersection is not found
883: while (current_segment_node && !found1)
884: current_segment = current_segment_node.key
885: segment_node = next_node.list.first
886: found2 = false
887: #While there are segments in next_node and the intersection is not found
888: while (segment_node && !found1 && !found2)
889: segment = segment_node.key
890: #Calculate ua
891: #Numerator
892: uan = (((segment.head.x - segment.tail.x)*(current_segment.tail.y - segment.tail.y)) - ((segment.head.y - segment.tail.y)*(current_segment.tail.x - segment.tail.x)))
893: #Denominator
894: uad = (((segment.head.y - segment.tail.y)*(current_segment.head.x - current_segment.tail.x)) - ((segment.head.x - segment.tail.x)*(current_segment.head.y - current_segment.tail.y)))
895: #The denominator is not going to be zero since the studied lines are not parallel neither coincident
896: ua = uan/uad
897:
898: #Calculate ub
899: #Numerator
900: ubn = (((current_segment.head.x - current_segment.tail.x)*(current_segment.tail.y - segment.tail.y)) - ((current_segment.head.y - current_segment.tail.y)*(current_segment.tail.x - segment.tail.x)))
901: #Denominator
902: ubd = uad
903: #The denominator is not going to be zero since the studied lines are not parallel neither coincident
904: ub = ubn/ubd
905: #if testing
906: #puts "ua: #{ua}, ub: #{ub}"
907: #end
908: if (ua > (1 + Constants::EPSILON)) #The current_segment does not intersect with the next_node line descriptor. Maybe some higher segment does intersect
909: found2 = true
910: elsif (ua < (0 - Constants::EPSILON))
911: found1 = true #We can stop searching this pair of lines, since there is not any pair of segments that intersect
912: elsif ((((0 - Constants::EPSILON) <= ub) && (ub <= (1 + Constants::EPSILON))) && (((0 - Constants::EPSILON) <= ua) && (ua <= (1 + Constants::EPSILON)))) #We have found the intersection
913: found1 = true #We can stop searching this pair of lines
914: label = Label.new(Constants::INTERSECTION_LABEL)
915: point_list = LinearLinkedList.new
916: if @p[layer_name].kind_of? LinearLinkedList
917: label_node = LinearLinkedListNode.new(label, point_list, nil)
918: else
919: label_node = BalancedBinaryTreeNode.new(Constants::BALANCED, nil, nil, label, point_list)
920: end
921:
922: inserted_node = @p[layer_name].insert_node(label_node) #Insert the node corresponding to the label of the point
923:
924: #Calculate the point
925: x = current_segment.tail.x + (ua * (current_segment.head.x - current_segment.tail.x))
926: y = current_segment.tail.y + (ua * (current_segment.head.y - current_segment.tail.y))
927: point = Point.new(x,y,0)
928: point_node = LinearLinkedListNode.new(OrderedPoint.new(point), nil, nil)
929: inserted_node.list.insert_node(point_node) #Insert the point node
930: #puts "point inserted: #{point.x}, #{point.y}"
931: end
932: segment_node = segment_node._next
933: end
934: current_segment_node = current_segment_node._next
935: end
936: end
937: j+=1
938: end
939: i+=1
940: end
941: }
942: end
| edges | an array of SketchUp Edges |
| points_and_materials | an array of pairs [Point3d, Material], both of them are classes of SketchUp |
| layer | name of the layer that is affected |
Refresh the internal representation of the shape according to the current SketchUp canvas content inside the group of the shape
# File lib/geometry.rb, line 677
677: def refresh_from_info(edges, points_and_materials, layer)
678: if (@s[layer] and @p[layer])
679: if @s[layer].kind_of? BalancedBinaryTree
680: @s[layer] = BalancedBinaryTree.new
681: else
682: @s[layer] = LinearLinkedList.new
683: end
684: @p[layer] = LinearLinkedList.new
685: edges.each { |e|
686: segment = Segment.new(OrderedPoint.new(e.start.position), OrderedPoint.new(e.end.position))
687: segment_list = LinearLinkedList.new
688:
689: if @s[layer].kind_of? LinearLinkedList
690: node = LinearLinkedListNode.new(segment.line_descriptor, segment_list, nil)
691: else
692: node = BalancedBinaryTreeNode.new(Constants::BALANCED, nil, nil, segment.line_descriptor, segment_list)
693: end
694:
695: inserted_node = @s[layer].insert_node(node) #Insert the node corresponding to the line descriptor of the segment
696:
697: #We create an auxiliar list filled with the new segment to add, in order to make the union and obtain the maximal lines
698: new_segment_list = LinearLinkedList.new
699: segment_node = LinearLinkedListNode.new(segment.clone, nil, nil)
700: new_segment_list.insert_node(segment_node)
701:
702: op_rel(inserted_node.list, new_segment_list, Constants::UNION, Constants::SEGMENTS)
703: }
704:
705: #Compound the label lists
706: points_and_materials.each { |pair|
707: point = OrderedPoint.new(pair[0])
708: label = Label.new(pair[1])
709: point_list = LinearLinkedList.new
710:
711: if @p[layer].kind_of? LinearLinkedList
712: node = LinearLinkedListNode.new(label, point_list, nil)
713: else
714: node = BalancedBinaryTreeNode.new(Constants::BALANCED, nil, nil, label, point_list)
715: end
716:
717: inserted_node = @p[layer].insert_node(node) #Insert the node corresponding to the label of the point
718:
719: point_node = LinearLinkedListNode.new(point, nil, nil)
720: inserted_node.list.insert_node(point_node) #Insert the point node
721: }
722: recompute_intersection_points
723: end
724: end
| path | path to save the shape in |
Saves the shape in the specified path
# File lib/geometry.rb, line 1246
1246: def save(path)
1247:
1248: if Shade.using_sketchup
1249: extension = ShadeUtils.get_extension(path)
1250:
1251: if extension == "skp"
1252: rules = Shade.project.execution.grammar.rules
1253: rules.each {|rule|
1254: rule.erase
1255: }
1256: Sketchup.active_model.entities
1257: Shade.project.execution.current_shape.erase
1258:
1259: Sketchup.active_model.active_entities.erase_entities(Sketchup.active_model.active_entities.to_a)
1260:
1261: self.paint
1262:
1263: path = path.tr("\\","/")
1264: Sketchup.active_model.save(path)
1265:
1266: ShadeUtils.prepare_canvas(false)
1267: rules.each {|rule|
1268: rule.repaint
1269: }
1270: Shade.project.execution.current_shape.paint
1271: elsif extension == "txt"
1272: File.open(path, 'w') do |f|
1273: Sketchup.active_model.layers.each { |layer|
1274: f.write("LAYER: #{layer.name}\n")
1275: @s[layer.name].reset_iterator
1276: while s_node = @s[layer.name].get_next
1277: s_node.list.reset_iterator
1278: while s = s_node.list.get_next
1279: f.write("S: #{s.key.tail.x.to_f.to_m} #{s.key.tail.y.to_f.to_m} #{s.key.head.x.to_f.to_m} #{s.key.head.y.to_f.to_m}\n")
1280: end
1281: end
1282: @p[layer.name].reset_iterator
1283: while l_node = @p[layer.name].get_next
1284: if !(l_node.key.value == Constants::INTERSECTION_LABEL)
1285: l_node.list.reset_iterator
1286: while l = l_node.list.get_next
1287: f.write("L: #{l.key.x.to_f.to_m} #{l.key.y.to_f.to_m} #{l_node.key.value}\n")
1288: end
1289: end
1290: end
1291: }
1292: end
1293: end
1294: else
1295: extension = ShadeUtils.get_extension(path)
1296: if extension == "txt"
1297: File.open(path, 'w') do |f|
1298: @s.each_key { |layer_name|
1299: f.write("LAYER: #{layer_name}\n")
1300: @s[layer_name].reset_iterator
1301: while s_node = @s[layer_name].get_next
1302: s_node.list.reset_iterator
1303: while s = s_node.list.get_next
1304: f.write("S: #{s.key.tail.x.to_f} #{s.key.tail.y.to_f} #{s.key.head.x.to_f} #{s.key.head.y.to_f}\n")
1305: end
1306: end
1307: @p[layer_name].reset_iterator
1308: while l_node = @p[layer_name].get_next
1309: if !(l_node.key.value == Constants::INTERSECTION_LABEL)
1310: l_node.list.reset_iterator
1311: while l = l_node.list.get_next
1312: f.write("L: #{l.key.x.to_f} #{l.key.y.to_f} #{l_node.key.value}\n")
1313: end
1314: end
1315: end
1316: }
1317: end
1318: end
1319: end
1320:
1321: end
| other_shape | another LabelledShape |
| op_rel_type | the operation or relation to perform. One of the following: Constants::UNION, Constants::INTERSECTION, Constants::DIFFERENCE, |
Constants::SUBSHAPE, Constants::EQUAL
| c | Constants::SEGMENTS if segments are affected, Constants::POINTS if points are affected. |
| returns | true iff the specified relation (subshape or equal) holds (or false if it does not hold). In case it is an operation, |
it just overwrites this shape with the resulting shape of the operation OR returns another shape in case it is an intersection
# File lib/geometry.rb, line 752
752: def shape_expression(other_shape, op_rel_type, c, print = false)
753:
754: global_flag = true
755:
756: result = LabelledShape.new(Array.new, Array.new)
757: if (c == Constants::SEGMENTS)
758: c1_hash = @s
759: c2_hash = other_shape.s
760: c3_hash = result.s
761: elsif (c==Constants::POINTS)
762: c1_hash = @p
763: c2_hash = other_shape.p
764: c3_hash = result.p
765: end
766:
767: c2_hash.each_key { |layer_name|
768:
769: flag = true
770: #Initialization
771:
772: c1 = c1_hash[layer_name]
773: c2 = c2_hash[layer_name]
774: c3 = c3_hash[layer_name]
775:
776: #NOTE: if c2 is empty, then the subshape relation DOES hold
777:
778: if (!c1)
779: if (c == Constants::SEGMENTS)
780: if self.kind_of? CurrentLabelledShape
781: c1 = BalancedBinaryTree.new
782: c1_hash[layer_name] = c1
783: else
784: c1 = LinearLinkedList.new
785: c1_hash[layer_name] = c1
786: end
787: else
788: c1 = LinearLinkedList.new
789: c1_hash[layer_name] = c1
790: end
791: end
792: if (!c2)
793: if (c == Constants::SEGMENTS)
794: if self.kind_of? CurrentLabelledShape
795: c2 = BalancedBinaryTree.new
796: c2_hash[layer_name] = c2
797: else
798: c2 = LinearLinkedList.new
799: c2_hash[layer_name] = c2
800: end
801: else
802: c2 = LinearLinkedList.new
803: c2_hash[layer_name] = c2
804: end
805: end
806: c2.reset_iterator
807: while ((v = c2.get_next) && flag)
808: if (!(v.key == Label.new(Constants::INTERSECTION_LABEL))) #we do not need to compare intersection points
809: u = c1.get_node(v.key)
810: if u #Matching keys found. Perform the appropiate action
811: if (op_rel_type == Constants::UNION) || (op_rel_type == Constants::INTERSECTION) || (op_rel_type == Constants::DIFFERENCE)
812: if (op_rel_type == Constants::UNION) || (op_rel_type == Constants::DIFFERENCE)
813: op_rel(u.list, v.list, op_rel_type, c)
814: else
815: result_list = op_rel(u.list, v.list, op_rel_type, c)
816: node = LinearLinkedListNode.new(v.key.clone, result_list, nil)
817: c3.insert_node node
818: end
819: if u.list.empty?
820: c1.delete_node(u.key)
821: flag = !c1.empty? #CHECK: es esto equivalente al alg. de krishnamurti??
822: end
823: elsif (op_rel_type == Constants::SUBSHAPE) || (op_rel_type == Constants::EQUAL)
824: flag = op_rel(u.list, v.list, op_rel_type, c)
825: end
826: else #There is no node with the same key value as v
827: if op_rel_type == Constants::UNION
828: if c1.kind_of? BalancedBinaryTree
829: new_node = BalancedBinaryTreeNode.new(0,nil,nil,v.key.clone, v.list.clone)
830: else
831: new_node = LinearLinkedListNode.new(v.key.clone, v.list.clone, nil)
832: end
833: c1.insert_node(new_node)
834: elsif (op_rel_type == Constants::SUBSHAPE) || (op_rel_type == Constants::EQUAL)
835: flag = false
836: end
837: end
838: end
839: end
840:
841: if (c == Constants::SEGMENTS)
842: #puts "#{layer_name}: #{flag}"
843: end
844:
845: global_flag = (global_flag and flag)
846: }
847:
848: #Finishing touches
849: if ((op_rel_type == Constants::SUBSHAPE) || (op_rel_type == Constants::EQUAL))
850: return global_flag
851: elsif (op_rel_type == Constants::INTERSECTION)
852: if (c == Constants::SEGMENTS)
853: result.recompute_intersection_points
854: end
855: return result
856: elsif (c == Constants::SEGMENTS)
857: self.recompute_intersection_points
858: end
859: end
First step of the difference algorithm of Krishnamurti
# File lib/geometry.rb, line 1111
1111: def step1_difference(list1, list2, working_line_node, linej_node)
1112: if (linej_node.key.tail < working_line_node.key.head)
1113: #step 3
1114: if (working_line_node.key.tail < linej_node.key.head)
1115: #step 5
1116: lineA = Segment.new(linej_node.key.tail, working_line_node.key.tail)
1117: lineB = Segment.new(working_line_node.key.head, linej_node.key.head)
1118: if (linej_node.key.tail < working_line_node.key.tail) && (linej_node.key.head <= working_line_node.key.head)
1119: linej_node.key = lineA.clone
1120: step4_difference(list1, list2, working_line_node, linej_node)
1121: elsif (working_line_node.key.tail <= linej_node.key.tail) && (working_line_node.key.head < linej_node.key.head)
1122: linej_node.key = lineB.clone
1123: step2_difference(list1, list2, working_line_node, linej_node)
1124: elsif (linej_node.key.tail < working_line_node.key.tail) && (working_line_node.key.head < linej_node.key.head)
1125: linej_node.key = lineB.clone
1126: list1.insert_node(LinearLinkedListNode.new(lineA.clone, nil, nil))
1127: step2_difference(list1, list2, working_line_node, linej_node)
1128: elsif (working_line_node.key.tail <= linej_node.key.tail) && (linej_node.key.head <= working_line_node.key.head)
1129: list1.delete_node(linej_node.key)
1130: step4_difference(list1, list2, working_line_node, linej_node)
1131: end
1132: else
1133: #step 4
1134: step4_difference(list1, list2, working_line_node, linej_node)
1135: end
1136: else
1137: #step 2
1138: step2_difference(list1, list2, working_line_node, linej_node)
1139: end
1140: end
First step of the intersection algorithm of Krishnamurti
# File lib/geometry.rb, line 1163
1163: def step1_intersection(list1, list2, list3, working_line_node, linej_node)
1164: if (linej_node.key.tail < working_line_node.key.head)
1165: #step 3
1166: if (working_line_node.key.tail < linej_node.key.head)
1167: #step 5
1168: #step 5.1
1169: if (linej_node.key.tail < working_line_node.key.tail)
1170: new_tail = working_line_node.key.tail
1171: else
1172: new_tail = linej_node.key.tail
1173: end
1174: if (working_line_node.key.head < linej_node.key.head) || (linej_node.key.head == working_line_node.key.head)
1175: #step 5.2
1176: new_head = working_line_node.key.head
1177: segmentk = Segment.new(new_tail, new_head)
1178: list3.insert_node(LinearLinkedListNode.new(segmentk, nil, nil))
1179: step2_intersection(list1, list2, list3, working_line_node, linej_node)
1180: else
1181: #step 5.3
1182: new_head = linej_node.key.head
1183: segmentk = Segment.new(new_tail, new_head)
1184: list3.insert_node(LinearLinkedListNode.new(segmentk, nil, nil))
1185: step4_intersection(list1, list2, list3, working_line_node, linej_node)
1186: end
1187: else
1188: #step 4
1189: step4_intersection(list1, list2, list3, working_line_node, linej_node)
1190: end
1191: else
1192: #step 2
1193: step2_intersection(list1, list2, list3, working_line_node, linej_node)
1194: end
1195: end
First step of the subshape algorithm of Krishnamurti
# File lib/geometry.rb, line 1214
1214: def step1_subshape(flag, list1, list2, working_line_node, linej_node)
1215: if (working_line_node.key.tail < linej_node.key.head)
1216: #step3
1217: if (linej_node.key.tail < working_line_node.key.head)
1218: #step4
1219: if ((working_line_node.key.tail >= linej_node.key.tail) && (working_line_node.key.head <= linej_node.key.head))
1220: #step 5
1221: if (working_line_node._next)
1222: working_line_node = working_line_node._next
1223: flag = step1_subshape(flag, list1, list2, working_line_node, linej_node)
1224: end
1225: else
1226: flag = false
1227: end
1228: else
1229: flag = false
1230: end
1231: else
1232: #step2
1233: if (linej_node._next)
1234: linej_node = linej_node._next
1235: flag = step1_subshape(flag, list1, list2, working_line_node, linej_node)
1236: else
1237: flag = false
1238: end
1239: end
1240: return flag
1241: end
First step of the union algorithm of Krishnamurti
# File lib/geometry.rb, line 1045
1045: def step1_union(list1, list2, working_line_node, linej_node)
1046: if (linej_node.key.tail <= working_line_node.key.head)
1047: #Step 3
1048: if (working_line_node.key.tail <= linej_node.key.head)
1049: #Step 5
1050: if (working_line_node.key.tail < linej_node.key.tail)
1051: linej_node.key.tail = working_line_node.key.tail.clone
1052: else
1053: working_line_node.key.tail = linej_node.key.tail.clone
1054: end
1055: #Step 6
1056: if (linej_node.key.head >= working_line_node.key.head)
1057: #GOTO step 2
1058: step2_union(list1, list2, working_line_node, linej_node)
1059: else
1060: list1.delete_node(linej_node.key)
1061: #Step 4
1062: step4_union(list1, list2, working_line_node, linej_node)
1063: end
1064:
1065: else
1066: #Step 4
1067: step4_union(list1, list2, working_line_node, linej_node)
1068: end
1069: else #the working line shares no common line with any line line(k>1) in list1, and working_line < linej
1070: #insert working_line into list1 as the maximal line immediately preceding linej in the list
1071: list1.insert_node(LinearLinkedListNode.new(working_line_node.key.clone, nil, nil))
1072: #Step 2
1073: step2_union(list1, list2, working_line_node, linej_node)
1074: end
1075: end
Second step of the difference algorithm of Krishnamurti
# File lib/geometry.rb, line 1143
1143: def step2_difference(list1, list2, working_line_node, linej_node)
1144: if (working_line_node._next)
1145: working_line_node = working_line_node._next
1146: step1_difference(list1, list2, working_line_node, linej_node)
1147: else
1148: return
1149: end
1150: end
Second step of the intersection algorithm of Krishnamurti
# File lib/geometry.rb, line 1198
1198: def step2_intersection(list1, list2, list3, working_line_node, linej_node)
1199: if (working_line_node._next)
1200: working_line_node = working_line_node._next
1201: step1_intersection(list1, list2, list3, working_line_node, linej_node)
1202: end
1203: end
Second step of the union algorithm of Krishnamurti
# File lib/geometry.rb, line 1078
1078: def step2_union(list1, list2, working_line_node, linej_node)
1079: if (working_line_node._next)
1080: working_line_node = working_line_node._next
1081: #GOTO step1
1082: step1_union(list1, list2, working_line_node, linej_node)
1083: else
1084: #Step 9
1085: return
1086: end
1087: end
Fourth step of the difference algorithm of Krishnamurti
# File lib/geometry.rb, line 1153
1153: def step4_difference(list1, list2, working_line_node, linej_node)
1154: if (linej_node._next)
1155: linej_node = linej_node._next
1156: step1_difference(list1, list2, working_line_node, linej_node)
1157: else
1158: return
1159: end
1160: end
Fourth step of the intersection algorithm of Krishnamurti
# File lib/geometry.rb, line 1206
1206: def step4_intersection(list1, list2, list3, working_line_node, linej_node)
1207: if (linej_node._next)
1208: linej_node = linej_node._next
1209: step1_intersection(list1, list2, list3, working_line, linej)
1210: end
1211: end
Fourth step of the union algorithm of Krishnamurti
# File lib/geometry.rb, line 1090
1090: def step4_union(list1, list2, working_line_node, linej_node)
1091: if (linej_node._next)
1092: linej_node = linej_node._next
1093: #GOTO step1
1094: step1_union(list1, list2, working_line_node, linej_node)
1095: else
1096: list1.insert_node(LinearLinkedListNode.new(working_line_node.key.clone, nil, nil))
1097: #GOTO Step 8
1098: step8_union(list1, list2, working_line_node, linej_node)
1099: end
1100: end
Eighth step of the union algorithm of Krishnamurti
# File lib/geometry.rb, line 1103
1103: def step8_union(list1, list2, working_line_node, linej_node)
1104: while (working_line_node)
1105: list1.insert_node(LinearLinkedListNode.new(working_line_node.key.clone, nil, nil))
1106: working_line_node = working_line_node._next
1107: end
1108: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.